package com.xls.boxlibrary.network;

import android.content.Context;
import android.text.TextUtils;

import com.orhanobut.logger.Logger;
import com.xls.boxlibrary.Consts.StateConsts;
import com.xls.boxlibrary.utils.AppUtils;
import com.xls.boxlibrary.utils.LUtils;
import com.xls.boxlibrary.utils.SPUtils;
import com.xls.commonlibrary.BuildConfig;
//import com.xls.commonlibrary.risk.RiskUtil;
import com.xls.commonlibrary.util.NetUtil;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.schedulers.Schedulers;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * 网络请求封装
 */
public class RetrofitBase {
    private static RetrofitBase retrofitBase;
    private static Retrofit retrofit;

    /**
     * 创建单例
     */
    public static RetrofitBase getInstace(final Context context) {
        if (retrofitBase == null) {
            synchronized (RetrofitBase.class) {
                retrofitBase = new RetrofitBase(context);
            }
        }
        return retrofitBase;
    }

    OkHttpClient okHttpClient;

    private RetrofitBase(final Context context) {
        if (null == retrofit) {
            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.interceptors().add(AddRequestHeader(context));
            openDebugLog(builder);
            builder.connectTimeout(StateConsts.CONNECT_TIMEOU, TimeUnit.SECONDS);
            okHttpClient = builder.build();
        }
    }


    public Retrofit setBaseUrl(String baseUrl) {

        return retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)//ip
                .client(okHttpClient)
                .addCallAdapterFactory(RxJava3CallAdapterFactory.create())//添加rxjava
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }


    /**
     * 开关debug  打印日志
     *
     * @param builder
     */
    private void openDebugLog(OkHttpClient.Builder builder) {
        if (StateConsts.isDebug) {
//              打印日志
            HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {

                @Override
                public void log(String message) {
                    if (BuildConfig.LOGGABLE) {
                        if (message.length() > 4000) {
                            for (int i = 0; i < message.length(); i += 4000) {
                                if (i + 4000 < message.length())
                                    LUtils.e("网络请求", message.substring(i, i + 4000));
                                else
                                    LUtils.e("网络请求", message.substring(i, message.length()));
                            }
                        } else
                            LUtils.e("网络请求", message);
                    }
                }
            });
            httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);//设置打印日志
            builder.addInterceptor(httpLoggingInterceptor);
        }
    }

    /***
     * 添加请求头
     */
    private Interceptor AddRequestHeader(final Context context) {
        return new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request original = chain.request();
                Response response = chain.proceed(getHttpHead(original, context));
//                ResponseBody responseBody = response.body();
//                BufferedSource source = responseBody.source();
//                source.request(Long.MAX_VALUE);
//                Buffer buffer = source.buffer();
//                Charset charset = StandardCharsets.UTF_8;
//                MediaType contentType = responseBody.contentType();
//                if (contentType != null) {
//                    charset = contentType.charset( StandardCharsets.UTF_8);
//                }
//                String bodyStr = buffer.clone().readString(charset);
//                Gson gson = new Gson();
//                HttpRequest httpRequest = gson.fromJson(bodyStr, HttpRequest.class);
//                TODO  拦截token  过期
//                synchronized (getInstace(context)){
//                    if (TextUtils.equals(httpRequest.getErrno(),StateConsts.CODE_401)){
//                        EventBus.getDefault().post(new MessageEvent(EventbusCode.CODE_OUTLOGIN));//强制退出登录
//                    }
//                }
                return response;
            }
        };
    }

    /**
     * 组装请求头
     *
     * @param original
     * @param context
     * @return
     */
    private Request getHttpHead(Request original, Context context) {
        Request.Builder requestBuilder = original.newBuilder()
                .addHeader("version", AppUtils.getVersionCode(context) + "")
                .addHeader("packageName", AppUtils.getPackageName(context))
                .addHeader("ipv4", NetUtil.getIPV4());
        requestBuilder.addHeader("User-Type", "app");
        String token = SPUtils.getLoginToken(context);
        if (!TextUtils.isEmpty(token)) {
            requestBuilder.addHeader("token", token);
        }

//        String tokenLianshanRisk = RiskUtil.getInstance().getToken();
//        Logger.d("=======tokenLianshanRisk===============%s",tokenLianshanRisk);
//        if (!TextUtils.isEmpty(tokenLianshanRisk)) {
//            requestBuilder.addHeader("tokenLianshanRisk", tokenLianshanRisk);
//        }
        return requestBuilder.build();
    }

    /**
     * 网络请求   监听开始结束
     *
     * @param context
     * @param observable
     * @param callBack
     * @param <T>
     * @return
     */
    public <T> void setSubscribe(Context context,
                                 Observable<HttpRequest<T>> observable,
                                 RequestCallBack<T> callBack) {
        observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).
                subscribe(new Subscriber<>(callBack, context));
    }
    public  <T> void setSubscribe(Context context,
                                  Observable<HttpRequest<T>> observable,
                                  RequestCallBackTwo<T> callBack) {
        observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).
                subscribe(new SubscriberTwo<>(callBack, context));
    }
}
